package org.vacoor.nothing.demo;

import com.google.common.collect.Lists;
import org.vacoor.nothing.common.util.CommandLineBuilder;
import org.vacoor.nothing.common.util.IOUtils;
import org.vacoor.nothing.common.util.StringUtils;
import sun.management.VMManagement;

import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.util.List;
import java.util.StringTokenizer;

/**
 * Created by Administrator on 2015/3/3.
 */
public class PathManager {
    public static String HOME_PATH = System.getProperty("user.home") + "/test";

    public static String getBinPath() {
        return getHomePath() + "/bin";
    }

    public static String getHomePath() {
        return HOME_PATH;
    }

    private static boolean isLocked() {
        return getLockFile().exists();
    }

    private static void lock() throws IOException {
        File lock = getLockFile();
        if (!lock.exists()) {
            lock.createNewFile();
        }
    }

    private static void unlock() {
        File lock = getLockFile();
        if (lock.exists() && lock.canWrite()) {
            lock.delete();
        }
    }

    private static File getLockFile() {
        return new File(getHomePath(), ".lock");
    }

    public static void clearLock() {
        unlock();
    }

    public static int scheduleRestartOnePer(String... beforeRestart) throws IOException {
        if (isLocked()) {
            unlock();
            return -1;
        }
        lock();

        restart();
        return 0;
//        return Restarter.scheduleRestart(beforeRestart);
    }

    public static final String SUN_JAVA_COMMAND = "sun.java.command";

    public static void restart() throws IOException {
        String command = System.getProperty(SUN_JAVA_COMMAND);
        StringTokenizer st = new StringTokenizer(command, " ");
        List<String> args = Lists.newArrayList();
        while (st.hasMoreElements()) {
            args.add(st.nextToken());
        }
        System.out.println("main: " + args);
        String clazz = args.remove(0);
        runMainClassInProcess(clazz, args);
    }

    public static void runMainClassInProcess(String clazz, List<String> args) throws IOException {
        final RuntimeMXBean mx = ManagementFactory.getRuntimeMXBean();
        final List<String> inputArgs = mx.getInputArguments();
        final String libraryPath = mx.getLibraryPath();         // -Djava.library.path=
        final String bootClassPath = mx.getBootClassPath();     // -Dsun.boot.class.path
        final String classpath = mx.getClassPath();
        final String javaName = SystemInfo.isWindows ? "java.exe" : "java";
        String java = null;
        // String javaVmExecutablePath = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
        // String classpath = System.getProperty("java.class.path");
        // final Process process = Runtime.getRuntime().exec("cmd " + javaVmExecutablePath + " -cp " + classpath + " com.intellij.idea.Main");

        // 首先遍历 PATH
        for (String path : StringUtils.tokenize(libraryPath, File.pathSeparator)) {
            File javaCommand = new File(path, javaName);
            if (javaCommand.exists() && javaCommand.canExecute()) {
                java = javaCommand.getAbsolutePath();
                break;
            }
        }
        java = null != java ? java : System.getProperty("java.home") + File.separator + "bin" + File.separator + javaName;

        CommandLineBuilder builder = new CommandLineBuilder(java);
        builder.addRawArgs(inputArgs);
        builder.addArgs("-classpath");
        builder.addRawArgs(classpath);

        builder.addArg(clazz);
        if (null != args) {
            builder.addArgs(args);
        }

        System.out.println(builder.getArgs());
        ProcessBuilder bu = new ProcessBuilder(builder.getArgs());
        Process proc = bu.start();
        IOUtils.flow(proc.getInputStream(), System.out, false, false);
        IOUtils.flow(proc.getErrorStream(), System.err, false, false);
    }


    public static void main(String[] args) throws IOException {
        System.setProperty("idea.paths.selector", "___");
        boolean supported = Restarter.isSupported();

        // 这里可执行命令必须使用绝对路径来处理, 即便在 Path 中也不行
        // restart 会执行完命令后重启, 如果执行的命令阻塞则一直等待
        // int exit = scheduleRestartOnePer("cmd", "/c", "mkdir c:\\____________");
        System.out.println("start");
        int exit = scheduleRestartOnePer();
        System.exit(exit);
//        Runtime.getRuntime().exec("notepad");
//        System.out.println(exit);
    }
}
